home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Telnet 2.7b5 / source / macros / macros.c next >
Encoding:
C/C++ Source or Header  |  1995-04-09  |  10.3 KB  |  526 lines  |  [TEXT/CWIE]

  1. /*
  2. *    macros.c
  3. *     by Gaige B. Paulsen
  4. *****************************************************************
  5. *    NCSA Telnet for the Macintosh                                *
  6. *                                                                *
  7. *    National Center for Supercomputing Applications                *
  8. *    Software Development Group                                    *
  9. *    152 Computing Applications Building                            *
  10. *    605 E. Springfield Ave.                                        *
  11. *    Champaign, IL  61820                                        *
  12. *                                                                *
  13. *    Copyright (c) 1986-1994,                                    *
  14. *    Board of Trustees of the University of Illinois                *
  15. *****************************************************************
  16. *    7/92    Moved here from event.c and maclook.c by JMB
  17. *    11/94    Rewritten to use handle based macros JMB
  18. */
  19.  
  20. #ifdef MPW
  21. #pragma segment Macros
  22. #endif
  23.  
  24.  
  25. #include "network.proto.h"                /* For netwrite proto */
  26. #include "wind.h"                /* For WindRec definition */
  27. #include "DlogUtils.proto.h"
  28. #include "parse.proto.h"
  29. #include "event.proto.h"
  30.  
  31. #include "vsdata.h"
  32. #include "vsinterf.proto.h"
  33.  
  34. #include "macros.proto.h"
  35.  
  36. #include "Sets.proto.h" //for CStringToFile
  37.  
  38. /* Macro Defines */
  39. #define MACRO_IP        0xff    /* Send IP number here */
  40. #define MACRO_LINES        0xfe    /* Send # of lines here */
  41. #define    MACRO_MAX_LEN    256        // Maximum macro length
  42.  
  43. extern Cursor *theCursors[];
  44.  
  45. Handle    gMacros[10];
  46.  
  47. void    MACROSunload(void) {}
  48.  
  49. void    initmacros( void)
  50. {
  51.     short i;
  52.  
  53.     for (i=0; i<10 ; i++) {
  54.         gMacros[i] = nil;
  55.         }
  56. }
  57.  
  58. void    setmacro(short n, char *s)            /* Set macro number <n> to the value of s */
  59. {
  60.     unsigned char    *p;
  61.     short    num, pos, escape;
  62.     short    len;
  63.     OSErr     memError;
  64.     
  65.     if (n<0  || n>9)
  66.         return;
  67.  
  68.     // Restrict the maximum length of macros to MACRO_MAX_LEN bytes
  69.     len = strlen(s)+1;
  70.     if (len > (MACRO_MAX_LEN - 1)) {
  71.         len = MACRO_MAX_LEN;
  72.         s[MACRO_MAX_LEN - 1] = 0;
  73.         }
  74.     
  75.     // If this is an empty string, remove whatever storage might have been used previously
  76.     // by this macro.
  77.     if (len == 1) {
  78.         if (gMacros[n] != nil) {
  79.             DisposeHandle(gMacros[n]);
  80.             gMacros[n] = nil;
  81.             }
  82.         return;
  83.         }
  84.         
  85.     // If neccessary, create storage for the macro
  86.     if (gMacros[n] == nil) {
  87.         gMacros[n] = myNewHandle(len);
  88.         if (gMacros[n] == nil) {        // Memory error
  89.             return;
  90.             }
  91.         }
  92.  
  93.     // Adjust the handle to the proper size (may be making an existing macro longer)
  94.     memError = mySetHandleSize(gMacros[n], len);
  95.     if (memError != noErr) {
  96.         return;
  97.         }
  98.     
  99.     HLock(gMacros[n]);
  100.     p = (unsigned char *)*gMacros[n];
  101.  
  102.     num = 0;
  103.     pos = 0;
  104.     escape = 0;
  105.     
  106.     while ( *s) {
  107.         if (escape) {
  108.             escape = 0;
  109.             switch (*s) {
  110.                 case 'i':
  111.                     if ( pos >0) {
  112.                         *p++=num;
  113.                         *p++=*s;
  114.                         pos=0;
  115.                         }
  116.                     *p++=MACRO_IP;
  117.                     break;
  118.                 case '#':
  119.                     if ( pos >0) {
  120.                         *p++=num;
  121.                         *p++=*s;
  122.                         pos=0;
  123.                         }
  124.                     *p++=MACRO_LINES;
  125.                     break;
  126.                 case 'n':
  127.                     if ( pos >0) {
  128.                         *p++=num;
  129.                         *p++=*s;
  130.                         pos=0;
  131.                         }
  132.                     *p++='\012';
  133.                     break;
  134.                 case 'r':
  135.                     if ( pos >0) {
  136.                         *p++=num;
  137.                         *p++=*s;
  138.                         pos=0;
  139.                         }
  140.                     *p++='\015';
  141.                     break;
  142.                 case 't':
  143.                     if ( pos >0) {
  144.                         *p++=num;
  145.                         *p++=*s;
  146.                         pos=0;
  147.                         }
  148.                     *p++='\t';
  149.                     break;
  150.                 case '"':
  151.                     if ( pos >0) {
  152.                         *p++=num;
  153.                         *p++=*s;
  154.                         pos=0;
  155.                         }
  156.                     *p++='\"';
  157.                     break;
  158.  
  159.                         
  160.                 case '\\':
  161.                     if ( pos >0) {
  162.                         *p++=num;
  163.                         escape=1;
  164.                         pos=0;
  165.                         num=0;
  166.                         }
  167.                     else
  168.                         *p++='\\';
  169.                     break;
  170.                 default:
  171.                     if (*s <='9' && *s >='0' && pos <3) {
  172.                         num= num*8+( *s -'0');
  173.                         pos++;
  174.                         escape=1;
  175.                         }
  176.                     else {
  177.                         if (pos ==0 && num==0) {
  178.                             *p++='\\';
  179.                             *p++=*s;
  180.                             }
  181.                         else {
  182.                             *p++=num;
  183.                             pos= 0;
  184.                             s--;            /* back up the buffer. */
  185.                             }
  186.                         }
  187.                     break;
  188.                 }
  189.             }
  190.         else {
  191.             if (*s=='\\') {
  192.                 num=0;
  193.                 pos=0;
  194.                 escape=1;
  195.                 }
  196.             else
  197.                 *p++=*s;
  198.             }
  199.         s++;
  200.         }
  201.  
  202.     if (pos >0) *p++=num;
  203.     
  204.     *p=0;
  205.     
  206.     // The resultant macro may be shorter than the input string due to escaped characters.
  207.     // So, recalculate the length of the macro and resize than handle if neccessary.
  208.     len = strlen(*gMacros[n])+1;
  209.     
  210.     HUnlock(gMacros[n]);
  211.     mySetHandleSize(gMacros[n], len);
  212. } /* setmacro */
  213.  
  214. short    sendmacro(struct WindRec *tw, short n)                /* send macro number n */
  215. {
  216.     char            temp[20];
  217.     unsigned char    *mp, *first;
  218.     unsigned char    myipnum[4];
  219.     
  220.     // Invalid number
  221.     if (n<0 || n>9) {
  222.         return -1;
  223.         }
  224.     
  225.     // Empty macro, so do nothing
  226.     if (gMacros[n] == nil) {
  227.         return 0;
  228.         }
  229.     
  230.     HLock(gMacros[n]);
  231.     mp = (unsigned char *)*gMacros[n];
  232.     first = mp;
  233.     
  234.     netgetip(myipnum);
  235.  
  236.     while ( *mp) {
  237.         if (*mp==MACRO_IP) {
  238.             SendStringAsIfTyped(tw, (char *)first, mp-first);
  239.             sprintf(temp,"%d.%d.%d.%d", myipnum[0], myipnum[1], myipnum[2], myipnum[3]);
  240.             SendStringAsIfTyped(tw, temp, strlen(temp));
  241.             first = mp+1;
  242.             }
  243.         else if ( *mp==MACRO_LINES) {
  244.             SendStringAsIfTyped(tw, (char *)first, mp-first);
  245.             sprintf(temp,"%d", VSgetlines(tw->vs));
  246.             SendStringAsIfTyped(tw, temp, strlen(temp));
  247.             first = mp+1;
  248.             }
  249.  
  250.         mp++;
  251.         }
  252.  
  253.     SendStringAsIfTyped(tw, (char *)first, mp-first);
  254.  
  255.     HUnlock(gMacros[n]);
  256.     return 0;
  257. }
  258.  
  259. short    getmacro(short n, char *dest, short room)
  260. {
  261.     unsigned char    *s;
  262.  
  263.     // Invalid number
  264.     if (n<0 || n>9) {
  265.         return -1;
  266.         }
  267.     
  268.     // Empty macro, so return empty string
  269.     if (gMacros[n] == nil) {
  270.         *dest = 0;
  271.         return 0;
  272.         }
  273.         
  274.     s = (unsigned char *)*gMacros[n];
  275.     
  276.     while (*s && (room >= 5)) {  // 5 = (size of \xxx) + (terminating \0)
  277.         switch( *s) {
  278.             case MACRO_IP :
  279.                 *dest++='\\';
  280.                 *dest++='i';
  281.                 room--;
  282.                 break;
  283.             case MACRO_LINES :
  284.                 *dest++='\\';
  285.                 *dest++='#';
  286.                 room--;
  287.                 break;
  288.             case '\\':
  289.                 *dest++='\\';
  290.                 *dest++='\\';
  291.                 room--;
  292.                 break;
  293.             case '\015':
  294.                 *dest++='\\';
  295.                 *dest++='r';
  296.                 room--;
  297.                 break;
  298.             case '\012':
  299.                 *dest++='\\';
  300.                 *dest++='n';
  301.                 room--;
  302.                 break;
  303.             case '\t':
  304.                 *dest++='\\';
  305.                 *dest++='t';
  306.                 room--;
  307.                 break;
  308.             default: 
  309.                 if ( isprint(*s)) 
  310.                     *dest++=*s;
  311.                 else {
  312.                     *dest++='\\';
  313.                     *dest++= (*s / 64) +'0';
  314.                     *dest++= ((*s % 64) / 8)+'0';
  315.                     *dest++= (*s % 8) +'0';
  316.                     room = room - 3;
  317.                     }
  318.                 break;
  319.             }
  320.         room--;
  321.         s++;
  322.         }
  323.  
  324.     *dest = 0;
  325.     return( 0);
  326. }
  327.  
  328. void    Macros( void)
  329. {
  330.     DialogPtr dtemp;
  331.     short dItem;
  332.     short i;
  333.     Rect dBox;
  334.     Str255 temp;
  335.     Handle MacString[10];
  336.  
  337.     SetCursor(theCursors[normcurs]);
  338.  
  339.     dtemp=GetNewMyDialog( MacroDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  340.  
  341.     for (i=0; i<10; i++) {
  342.         getmacro(i, (char *) &temp, 256);        /* BYU LSC */
  343.         c2pstr((char *)temp);                                /* BYU LSC */
  344.         GetDItem( dtemp, i+13, &dItem, &MacString[i], &dBox);
  345.         SetIText( MacString[i], temp );
  346.         }
  347.  
  348.     dItem=0;                                /* initially no hits */
  349.     while((dItem>2) || (dItem==0)) {        /* While we are in the loop */
  350.         ModalDialog(DLOGwOK_CancelUPP,&dItem);
  351.         switch(dItem) {
  352.         case (MacroExport):
  353.             for (i=0; i<10; i++) {
  354.                 GetIText( MacString[i], temp);
  355.                 p2cstr(temp);
  356.                 setmacro(i, (char *) &temp);
  357.             }
  358.             saveMacros();
  359.             break;
  360.         case (MacroImport):
  361.             loadMacros((FSSpec *) NULL);
  362.             for (i=0; i<10; i++) {
  363.                 getmacro(i, (char *) &temp, 256);        
  364.                 c2pstr((char *)temp);                                
  365.                 GetDItem( dtemp, i+13, &dItem, &MacString[i], &dBox);
  366.                 SetIText( MacString[i], temp );
  367.             }
  368.             break;
  369.         default:
  370.             if (dItem >2 && dItem <13) 
  371.             {
  372.                 i=dItem-3;
  373.                 getmacro( i, (char *) &temp, 256);            /* BYU LSC */
  374.                 c2pstr((char *)temp);
  375.                 GetDItem( dtemp, i+13, &dItem, &MacString[i], &dBox);
  376.                 SetIText( MacString[i], temp );                /* BYU LSC - Revert the mother */
  377.                 SelIText( dtemp, i+13, 0, 32767);                /* And select it... */
  378.             }    
  379.             break;
  380.         }
  381.     }
  382.         
  383.     updateCursor(1);
  384.     
  385.     if (dItem==DLOGCancel) {
  386.             DisposDialog( dtemp);
  387.             return;
  388.             }
  389.  
  390.     for (i=0; i<10; i++) {
  391.         GetIText( MacString[i], temp);
  392.         p2cstr(temp);
  393.         setmacro(i, (char *) &temp);
  394.         }
  395.  
  396.     DisposDialog( dtemp);
  397. }
  398.  
  399. void saveMacros(void)
  400. {
  401.     SFReply        whereReply;
  402.     short         refNum,exist;
  403.     FSSpec        macroFile;
  404.     long        junk;
  405.     short         i;
  406.     char        temp[256], temp2[256];
  407.     Point        where;
  408.     OSErr        err;
  409.     Str255        tempString,tempString2;
  410.  
  411.     where.h = 100; where.v = 100;
  412.  
  413.     GetIndString(tempString,MISC_STRINGS,SAVE_MACROS_STRING);
  414.     GetIndString(tempString2,MISC_STRINGS,DEFAULT_MACRO_SET_NAME);
  415.     
  416.     SFPutFile( where, tempString, tempString2, 0L, &whereReply);
  417.  
  418.     if (!whereReply.good)
  419.         return;
  420.  
  421.     BlockMoveData(&whereReply.fName, macroFile.name, (*whereReply.fName)+1); 
  422.     GetWDInfo(whereReply.vRefNum, ¯oFile.vRefNum, ¯oFile.parID, &junk);
  423.  
  424.     if ((err = HCreate(macroFile.vRefNum, macroFile.parID, 
  425.             macroFile.name, kNCSACreatorSignature, 'TEXT')) == dupFNErr)
  426.         exist = 1;
  427.     
  428.     err = HOpen(macroFile.vRefNum, macroFile.parID, macroFile.name, fsWrPerm, &refNum);
  429.  
  430.     if (exist) 
  431.         SetEOF(refNum, 0L);
  432.  
  433.     
  434.     for (i = 0; i < 10; i++)
  435.     {
  436.         getmacro(i, temp, sizeof(temp));            
  437.         sprintf(temp2, "key%d = \"", i);        
  438.         CStringToFile(refNum,(unsigned char *) temp2);
  439.         if (*temp) 
  440.         {                                    
  441.             CStringToFile(refNum,(unsigned char *) temp);
  442.         }
  443.         strcpy(temp2,"\"\015");
  444.         CStringToFile(refNum,(unsigned char *) temp2);    
  445.  
  446.     }
  447.     FSClose(refNum);
  448.     
  449. }
  450.  
  451. void loadMacros(FSSpec *theFile)
  452. {
  453.     SFReply        sfr;
  454.     long        junk;
  455.     SFTypeList    typesok = {'TEXT'};
  456.     Point        where;
  457.     FSSpec        macros;
  458.     OSErr         err;
  459.     short         fileRef;
  460.     where.h=100;where.v=100;
  461.     if (theFile == 0L)
  462.     {
  463.         SFGetFile( where, NULL, 0L, 1, typesok, 0L, &sfr);
  464.         if (!sfr.good) return;
  465.         BlockMove(&sfr.fName, macros.name, (*sfr.fName)+1); 
  466.         GetWDInfo(sfr.vRefNum, ¯os.vRefNum, ¯os.parID, &junk);
  467.         err = HOpen(macros.vRefNum, macros.parID, macros.name, fsRdPerm, &fileRef);
  468.     }
  469.     else
  470.         err = HOpen(theFile->vRefNum, theFile->parID, theFile->name, fsRdPerm, &fileRef);
  471.     
  472.     if (err != noErr)
  473.         return;    
  474.     parseMacroFile(fileRef);
  475.     FSClose(fileRef);
  476. }
  477.  
  478. void parseMacroFile(short fileRef)
  479. {
  480.     unsigned char buffer[300],*bufferPtr;
  481.     unsigned char newMacro[256], *newMacroPtr;
  482.     OSErr fileErr = noErr;
  483.     short numMacrosRead = 0;
  484.     short totalLen,i;
  485.     long count=1;
  486.  
  487.     bufferPtr = buffer; 
  488.  
  489.     for(i = 0; i < 10; i++)
  490.     {
  491.         if (gMacros[i] != NULL)
  492.             DisposHandle(gMacros[i]);
  493.     }
  494.     initmacros();  //sets all handles to null
  495.  
  496.     while ((fileErr != eofErr)&&(numMacrosRead < 10))
  497.     {
  498.         fileErr = FSRead(fileRef,&count,bufferPtr);
  499.         while((*bufferPtr != 0x0D)&&(fileErr != eofErr))    //while not CR or EOF
  500.         {
  501.         
  502.             ++bufferPtr;
  503.             fileErr = FSRead(fileRef,&count,bufferPtr);
  504.         
  505.         }
  506.         
  507.         totalLen = bufferPtr-buffer;
  508.         bufferPtr = buffer;
  509.         newMacroPtr = newMacro;
  510.         while((*bufferPtr++ != '"')&&(totalLen != 0))
  511.             --totalLen;
  512.  
  513.         while((*bufferPtr != '"')&&(totalLen != 0))
  514.         {
  515.             *newMacroPtr++ = *bufferPtr++;
  516.             --totalLen;
  517.         }        
  518.         *newMacroPtr = NULL; //make this a C string
  519.  
  520.         setmacro(numMacrosRead,(char *)newMacro);
  521.         bufferPtr = buffer;
  522.         ++numMacrosRead;
  523.     }
  524. }
  525.         
  526.